package com.frejoys.store.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.frejoys.common.aop.Authority;
import com.frejoys.common.aop.Authorization;
import com.frejoys.common.aop.VerifyStore;
import com.frejoys.common.constant.CommonConstant;
import com.frejoys.common.dto.admin.StoreAddDto;
import com.frejoys.common.dto.admin.StoreListDto;
import com.frejoys.common.dto.admin.StoreUpDto;
import com.frejoys.common.dto.app.AgentUserIdDto;
import com.frejoys.common.dto.common.IdDto;
import com.frejoys.common.dto.store.CoreDataDto;
import com.frejoys.common.enums.EFileSize;
import com.frejoys.common.enums.EShelves;
import com.frejoys.common.enums.EStoreCodType;
import com.frejoys.common.error.HttpStatus;
import com.frejoys.common.exception.GeneralException;
import com.frejoys.common.response.Result;
import com.frejoys.common.util.*;
import com.frejoys.common.vo.admin.StoreIdAndNameListVo;
import com.frejoys.common.vo.store.*;
import com.frejoys.dao.entity.Store;
import com.frejoys.dao.entity.StoreActivity;
import com.frejoys.dao.entity.StoreCode;
import com.frejoys.dao.entity.StoreStatisticsDay;
import com.frejoys.dao.mapper.StoreActivityMapper;
import com.frejoys.service.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Tag(name = "店铺", description = "商家端店铺管理")
@RestController
@RequiredArgsConstructor
@RequestMapping(CommonConstant.routePrefixStore)
@Authorization(Authority.Private)
public class MallStoreController {

    private final StoreService storeService;

    private final CategoryService categoryService;

    private final StoreWalletService storeWalletService;

    private final StoreStatisticsDayService storeStatisticsDayService;

    private final RedissonClient redissonClient;

    private final StoreCodeService storeCodeService;

    private final EventPublisherService eventPublisherService;

    private final StoreCategoryService storeCategoryService;

    private final StoreActivityMapper storeActivityMapper;

    private final StoreActivityService storeActivityService;

    @Authorization(Authority.Protected)
    @Operation(summary = "店铺列表")
    @PostMapping("/store/list")
    public Result<List<StoreVo>> storeList(@RequestBody @Validated StoreListDto dto) {
        List<StoreVo> list = new ArrayList<>();

        List<Store> stores = storeService.listBusinessStore(dto, RequestUtil.userId());
        if (stores.isEmpty()) {
            return Result.success(list);
        }

        List<Integer> storeIds = stores.stream().map(Store::getId).toList();

        //查询店铺活动
//        LambdaQueryWrapper<StoreActivity> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.select(StoreActivity::getMoney,StoreActivity::getStoreId,StoreActivity::getTotalMoney,StoreActivity::getType)
//                .in(StoreActivity::getStoreId,storeIds)
//                .eq(StoreActivity::getShelves, EShelves.onSale.getValue());
//        List<StoreActivity> storeActivityList = storeActivityMapper.selectList(queryWrapper);
//        Map<Integer, StoreActivity> storeActivityMap = storeActivityList.stream().collect(Collectors.toMap(StoreActivity::getStoreId, storeActivity -> storeActivity));

        //查询品类
        Map<Integer, String> categoryNameMap = categoryService.getIdNameMap(storeIds);
        //查询钱包
        Map<Integer, BigDecimal> storeIdMoneyMap = storeWalletService.getStoreIdMoneyMap(storeIds);
        List<StoreCode> storeCodes = storeCodeService.getOnlineCode();
        Map<Integer, String> storeCodeMap = new HashMap<>();
        if (CollectionUtil.isNotEmpty(storeCodes)) {
            storeCodeMap = storeCodes.stream().collect(Collectors.toMap(StoreCode::getStoreId, StoreCode::getPayCode));
        }
        for (Store e : stores) {
            StoreVo vo = new StoreVo();
            BeanUtil.copyProperties(e,vo);
            vo.setCategoryName(categoryNameMap.get(e.getCategoryId()));
            if (StrUtil.isNotEmpty(e.getCover())){
                vo.setCover(CommonUtil.getFirstCover(e.getCover()));
            }
            vo.setLogo(AppConfigUtil.getUrlPrefix(e.getLogo(), EFileSize.logo.getValue()));
            vo.setCover(AppConfigUtil.getUrlPrefix(e.getCover()));
            vo.setCoverShow(AppConfigUtil.getUrlPrefix(e.getCoverShow()));
            vo.setStoreWalletBalance(storeIdMoneyMap.get(e.getId()));
            String payCode = storeCodeMap.get(e.getId());

//            if (storeActivityMap.containsKey(e.getId())){
//                StoreActivity storeActivity = storeActivityMap.get(e.getId());
//                vo.setStoreActivityMoney(storeActivity.getMoney());
//                vo.setStoreActivityTotalMoney(storeActivity.getTotalMoney());
//                vo.setStoreActivityType(storeActivity.getType());
//            }

            if (StrUtil.isEmpty(payCode)) {
                eventPublisherService.sendStoreQrCodeService(e.getId(), EStoreCodType.online.getValue());
            }
            vo.setPayCodeUrl(AppConfigUtil.getUrlPrefix(payCode,EFileSize.qrcode.getValue()));

            list.add(vo);
        }

        return Result.success(list);
    }

    @Operation(summary = "店铺详情")
    @PostMapping("/store/detail")
    public Result<StoreDetailVo> storeDetail(@RequestBody @Validated IdDto dto) {
        Store store = storeService.getById(dto.getId());
        if (store == null) {
            throw new GeneralException(HttpStatus.storeNotFound);
        }
        //查询店铺活动
        LambdaQueryWrapper<StoreActivity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StoreActivity::getStoreId,dto.getId())
                .le(StoreActivity::getStartTime, TimeUtil.unixTime())
                .ge(StoreActivity::getEndTime,TimeUtil.unixTime())
                .eq(StoreActivity::getShelves, EShelves.onSale.getValue());
        StoreActivity storeActivity = storeActivityService.getOnly(wrapper);

        StoreDetailVo storeVo = BeanUtil.copyProperties(store, StoreDetailVo.class);
        Map<Integer, String> categoryNameMap = categoryService.getIdNameMap();
        storeVo.setStoreCategoryVos(storeCategoryService.list(dto.getId()));

        storeVo.setFLogo(storeVo.getLogo());
        storeVo.setFCover(storeVo.getCover());
        storeVo.setFCoverShow(storeVo.getCoverShow());
        storeVo.setCategoryName(categoryNameMap.get(storeVo.getCategoryId()));
        storeVo.setCover(AppConfigUtil.getUrlPrefix(storeVo.getCover()));
        storeVo.setCoverShow(AppConfigUtil.getUrlPrefix(storeVo.getCoverShow()));
        storeVo.setLogo(AppConfigUtil.getUrlPrefix(storeVo.getLogo(),EFileSize.logo.getValue()));
        storeVo.setPayCode(AppConfigUtil.getUrlPrefix(storeCodeService.getOnlineCode(dto.getId())));
        // 获取当日销售额统计
        LambdaQueryWrapper<StoreStatisticsDay> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StoreStatisticsDay::getYmd, new SimpleDateFormat("yyyyMMdd").format(new Date()))
                .eq(StoreStatisticsDay::getStoreId,dto.getId());
        StoreStatisticsDay storeStatisticsDay = storeStatisticsDayService.getOnly(queryWrapper);
        if (storeStatisticsDay != null) {
            storeVo.setMoney(storeStatisticsDay.getMoney());
            storeVo.setCommissionMoney(storeStatisticsDay.getCommissionMoney());
            storeVo.setPromotionMoney(storeStatisticsDay.getPromotionMoney());
            storeVo.setRebateMoney(storeStatisticsDay.getRebateMoney());
        }
        if (storeActivity != null){
            StoreActivityDetailsVo vo = new StoreActivityDetailsVo();
            vo.setStoreActivityMoney(storeActivity.getMoney());
            vo.setStoreActivityTotalMoney(storeActivity.getTotalMoney());
            vo.setStoreActivityType(storeActivity.getType());
            vo.setPersonCount(storeActivity.getPersonCount());
            vo.setTotalPersonCount(storeActivity.getTotalPersonCount());
            storeVo.setStoreActivityDetailsVo(vo);
        }
        return Result.success(storeVo);
    }

    @VerifyStore
    @Operation(summary = "添加店铺")
    @PostMapping("/store/addInfo")
    public Result addStore(@RequestBody @Validated StoreAddDto dto) {

        RLock lock = redissonClient.getLock(CacheKeyUtil.storeAddLockCacheKey(RequestUtil.userId()));

        Store store = null;

        if (lock.tryLock()) {
            try {

                store = storeService.addInfo(dto, RequestUtil.userId());

            } finally {
                if (lock.isLocked() && lock.isHeldByCurrentThread()) {
                    lock.unlock();
                }
            }
        } else {
            throw new GeneralException(HttpStatus.beingProcessed);
        }

        if (store != null && store.getId() != null) {
            // 生成店铺线上支付码事件
            eventPublisherService.sendStoreQrCodeService(store.getId(), EStoreCodType.online.getValue());
        }

        return Result.success();
    }

    @VerifyStore
    @Operation(summary = "编辑店铺")
    @PostMapping("/store/upInfo")
    public Result upStore(@RequestBody @Validated StoreUpDto dto) {

        RLock lock = redissonClient.getLock(CacheKeyUtil.storeEditLockCacheKey(RequestUtil.userId()));

        if (lock.tryLock()) {
            try {

                storeService.upInfo(dto);

            } finally {
                if (lock.isLocked() && lock.isHeldByCurrentThread()) {
                    lock.unlock();
                }
            }
        } else {
            throw new GeneralException(HttpStatus.beingProcessed);
        }

        return Result.success();
    }

    @Authorization(Authority.Protected)
    @PostMapping("/store/monthData")
    @Operation(summary = "获取本月数据")
    public Result<MonthDataVo> monthData(){
        return Result.success(storeService.monthData(RequestUtil.userId()));
    }

    @PostMapping("/storeWalletLog/coreData")
    @Operation(summary = "核心数据")
    public Result<CoreDataVo> coreData(@RequestBody @Validated CoreDataDto dto) {
        return Result.success(storeService.coreData(dto));
    }


    @PostMapping("/store/storeNameListInfo")
    @Operation(summary = "获取店铺名字和logo列表")
    public Result<List<StoreIdAndNameListVo>> storeNameListInfo(){
        return Result.success(storeService.storeNameListInfo(RequestUtil.userId()));
    }
}
